package api

import (
	"net/http"
	"path/filepath"
	"strconv"
	"strings"

	"github.com/julienschmidt/httprouter"
	"learning.com/edu/models"
	"learning.com/edu/utils/validator"
)

/**
 * 获取所有课程分类
 */
func (api *Api) getAllCategories(w http.ResponseWriter, r *http.Request) { 
	categories, err := api.models.Courses.GetAllCategories()
	if err != nil {
		api.h.ServerErrorResponse(w, r, err);
		return
	}

	data := map[string]interface{} {
		"categories": categories,
	}
	resp := api.h.NewResponse(0, data)
	err = api.h.WriteJSON(w, http.StatusOK, resp, nil)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
	}
}

/**
 * 获取课程的top关键字
 */
func (api *Api) getTopCourseKeys(w http.ResponseWriter, r *http.Request) {
	keys, err := api.models.Courses.GetTopCourseKeys()
	if err != nil {
		api.h.ServerErrorResponse(w, r, err);
		return
	}

	data := map[string]interface{} {
		"keys": keys,
	}
	resp := api.h.NewResponse(0, data)
	err = api.h.WriteJSON(w, http.StatusOK, resp, nil)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
	}
}

/**
 * 获取课程列表
 */
func (api *Api) getCourseList(w http.ResponseWriter, r *http.Request) { 
	var input struct {
		categoryId int
		models.PageFilter
	}

	v := validator.New()
	qs := r.URL.Query()
	input.categoryId = api.h.ReadInt(qs, "categoryId", 0, v)
	input.PageFilter.Page = api.h.ReadInt(qs, "page", 1, v)
	input.PageFilter.PageSize = api.h.ReadInt(qs, "page_size", 20, v)

	// 验证过滤参数
	if input.PageFilter.ValidateFilters(v); !v.Valid() {
		api.h.FailedValidationResponse(w, r, v.Errors)
		return
	}

	courses, meta, err := api.models.Courses.GetCourseList(input.categoryId, 
		&input.PageFilter)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
		return
	}

	data := map[string]interface{} {
		"courses": courses,
		"page_meta": meta,
	}
	resp := api.h.NewResponse(0, data)
	err = api.h.WriteJSON(w, http.StatusOK, resp, nil)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
	}
}

/**
 * 获取课程封面
 */
func (api *Api) getCourseImage(w http.ResponseWriter, r *http.Request) {
	params := httprouter.ParamsFromContext(r.Context())
	file := params.ByName("file")
	imagePath := filepath.Join(api.config.Path.CourseImagesPath(), file)
	http.ServeFile(w, r, imagePath)
}

/**
 * 搜索课程
 */
func (api *Api) searchCourse(w http.ResponseWriter, r *http.Request) {
	var input struct {
		key string
		models.PageFilter
	}

	v := validator.New()
	qs := r.URL.Query()
	input.key = api.h.ReadString(qs, "key", "")
	input.PageFilter.Page = api.h.ReadInt(qs, "page", 1, v)
	input.PageFilter.PageSize = api.h.ReadInt(qs, "page_size", 20, v)

	// 去掉空格
	input.key = strings.TrimSpace(input.key)

	// 验证过滤参数
	v.Check(input.key != "", "search_key", "不能为空")
	if input.PageFilter.ValidateFilters(v); !v.Valid() {
		api.h.FailedValidationResponse(w, r, v.Errors)
		return
	}

	courses, meta, err := api.models.Courses.SearchCourse(input.key, &input.PageFilter)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
		return
	}
	data := map[string]interface{} {
		"courses": courses,
		"page_meta": meta,
	}
	resp := api.h.NewResponse(0, data)
	err = api.h.WriteJSON(w, http.StatusOK, resp, nil)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
	}
}

/**
 * 获取课程详情
 */
func (api *Api) getCourseDetail(w http.ResponseWriter, r *http.Request) {
	v := validator.New()
	qs := r.URL.Query()
	cid := api.h.ReadInt64(qs, "course_id", 0, v)
	v.Check(cid > 0, "course_id", "course_id不能为空")
	if !v.Valid() {
		api.h.FailedValidationResponse(w, r, v.Errors)
		return
	}
	// 获取用户信息
	user := api.middleware.ContextGetUser(r)
	course, err := api.models.Courses.GetCourseDetail(cid, user.ID)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
		return
	}

	data := map[string]interface{} {
		"course": course,
	}
	resp := api.h.NewResponse(0, data)
	err = api.h.WriteJSON(w, http.StatusOK, resp, nil)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
	}
}

/**
 * 获取视频文件
 */
func (api *Api) getVideoFile(w http.ResponseWriter, r *http.Request) {
	params := httprouter.ParamsFromContext(r.Context())
	sId := params.ByName("id")
	videoId, err := strconv.ParseInt(sId, 10, 64)
	if err != nil || videoId < 1 {
		api.h.FailedValidationResponse(w, r, 
			map[string]string{"video_id" : "video_id不能为空"})
		return
	}

	fileName, folder, err := api.models.Courses.GetCourseVideoFileAndFolder(videoId)
	if err != nil {
		api.h.ServerErrorResponse(w, r, err)
		return
	}

	videoPath := filepath.Join(api.config.Path.LecturesPath(), folder, 
		"videos", fileName)
	http.ServeFile(w, r, videoPath)
}

/**
 * 课程相关路由
 */
func (api *Api) courseRoutes(router *httprouter.Router) {
	// 获取课程分类
	router.HandlerFunc(http.MethodGet, "/v1/course/categories", api.getAllCategories)

	// 获取课程分类键
	router.HandlerFunc(http.MethodGet, "/v1/course/topCourseKeys", api.getTopCourseKeys)

	// 获取课程列表
	router.HandlerFunc(http.MethodGet, "/v1/course/list", api.getCourseList)

	// 获取课程封面
	router.HandlerFunc(http.MethodGet, "/v1/course/image/:file", api.getCourseImage)

	// 搜索课程
	router.HandlerFunc(http.MethodGet, "/v1/course/search", api.searchCourse)

	// 获取课程详情
	router.HandlerFunc(http.MethodGet, "/v1/course/detail", api.getCourseDetail)
}